# Here we are importing our R libraries that we will be using
# for the Arabic Papyri Network Project
library('igraph')
##
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
## The following object is masked from 'package:base':
##
## union
library('visNetwork')
##
## Attaching package: 'visNetwork'
## The following object is masked from 'package:igraph':
##
## %>%
Importing our data
# here we are importing our csv files that have our papyri data
nodes <- read.csv('nodes.csv', header = T, as.is = T)
edges <- read.csv('edges.csv', header = T, as.is = T)
#This creates our base network and dumps our node and edge data into one place
net <-graph_from_data_frame(d = edges, vertices = nodes, directed = TRUE)
Print our Nodes
V(net)
## + 36/36 vertices, named:
## [1] Abd Allah b. As'ad b. Abi Muslim
## [3] Yazid b. 'Ali Khalid
## [5] Peter the Symmachos Juzayy
## [7] Yazid Anonymous Symmachos
## [9] Rashid People of Narmuda
## [11] Qarina Anonymous Amir
## [13] Najid b. Muslim Abu (missing)
## [15] Awn b. Nafi' so and so son of ....man
## [17] two sons of Da'ud Jarid b. As'ad
## [19] George the Symmachos Abu Dawud
## + ... omitted several vertices
Print our Edges
E(net)
## + 78/78 edges (vertex names):
## [1] Najid b. Muslim ->Abd Allah b. As'ad
## [2] Anonymous Amir ->Najid b. Muslim
## [3] Yazid b. 'Ali ->Najid b. Muslim
## [4] Najid b. Muslim ->Abd Allah b. As'ad
## [5] Anonymous Amir ->Najid b. Muslim
## [6] Najid b. Muslim ->Abd Allah b. As'ad
## [7] Anonymous Amir ->Najid b. Muslim
## [8] Najid b. Muslim ->Abd Allah b. As'ad
## [9] Anonymous Amir ->Najid b. Muslim
## [10] Najid b. Muslim ->Abd Allah b. As'ad
## + ... omitted several edges
Attributes
# With R we can assign attributes to your nodes and edges.
# To make sure these attributes were properly assigned, we can
# Print them just like our edges and nodes
E(net)$Citation
## [1] "P.Mich.inv.5558(1)" "P.Mich.inv.5558(1)"
## [3] "P.Mich.inv.5558(1)" "P.Mich.inv. 5629"
## [5] "P.Vindob. A P 11045" "P.Vindob. A P 11045"
## [7] "P.Mich.inv. 5624" "P.Mich.inv. 5624"
## [9] "P.Mich.inv. 5578(1)" "P.Mich.inv. 5578(1)"
## [11] "P.Vindob. A P 11253" "P.Vindob. A P 11253"
## [13] "P.Mich.inv. 5627" "P.Mich.inv. 5627"
## [15] "P.Mich.inv. 5558(2)" "P.Mich.inv 5578(3)"
## [17] "P.Mich.inv 5578(3)" "P.Mich.inv 5578(5)a"
## [19] "P.Mich.inv 5578(5)b" "P.Mich.inv 5578(5)b"
## [21] "P.Mich.inv 5578(7)" "P.Mich.inv 5578(6)"
## [23] "P.Mich.inv 5578(6)" "P.Mich.inv 5610"
## [25] "P.Mich.inv 5610" "P.Mich.inv 5610"
## [27] "P.Mich.inv 5613(b)" "P.Mich.inv 5613(b)"
## [29] "P.Mich.inv 5613(b)" "P.Mich.inv 5613(b)"
## [31] "P.Mich.inv 5613(b)" "P.Mich.inv 5613(b)"
## [33] "P.Mich.inv 5625(a)" "P.Mich.inv 5625(a)"
## [35] "P.Mich.inv 5625(a)" "P.Mich.inv 5625(a)"
## [37] "P.Mich.inv 5625(a)" "P.Mich.inv 5625(a)"
## [39] "P.Mich.inv 5625(a)" "P.Mich.inv 5620"
## [41] "P.Mich.inv 5620" "P.Mich.inv 5620"
## [43] "P.Princeton AM 133995(8)" "P.Mich.inv 5619"
## [45] "P.Mich.inv 5619" "P.Vindob. A P 11252"
## [47] "P.Vindob. A P 11252" "P.Vindob. A P 11252"
## [49] "P.Mich.inv 5613(a)" "P.Mich.inv 5613(a)"
## [51] "P.Mich.inv 5632" "P.Mich.inv 5578(9)"
## [53] "P.Mich.inv 5578(9)" "P.Mich.inv 5578(9)"
## [55] "P.Mich.inv 5578(9)" "P.Mich.inv 5578(9)"
## [57] "P.Mich.inv 5622" "P.Mich.inv 5622"
## [59] "P.Mich.inv 5609" "P.Mich.inv 5609"
## [61] "P.Mich.inv 5609" "P.Mich.inv 5609"
## [63] "P.Mich.inv 5609" "P.Mich.inv 5609"
## [65] "P.Mich.inv 5621" "P.Mich.inv 5623"
## [67] "P.Mich.inv 5623" "P.Mich.inv 5623"
## [69] "P.Mich.inv 5626(b)" "P.Mich.inv 5631"
## [71] "Chester Beatty Pp 8" "Mich. Pap. A 847"
## [73] "P.Mich.inv. 5578(8)" "P.Vindob. A P 25"
## [75] "P.Vindob. A P 1874" "P.Vindob. A P 1875 side A"
## [77] "P.Vindob. A P 1875 side A" "P.Vindob. A P 1875 verso"
# This prints the rank of our Nodes
V(net)$Rank
## [1] "Official" "Official" "Treasurer" "Resident"
## [5] "Symmachos" "Sahib al-Ma'a" "Official" "Symmachos"
## [9] "Sahib al-Ma'a" "Village" "Sahib" "Amir"
## [13] "Sahib" "Official" "Official" "Resident"
## [17] "Resident" "Sahib" "Symmachos" "Symmachos"
## [21] "Official" "Official" "Freedman" "Official"
## [25] "Resident" "Resident" "Friend" "Oil Man"
## [29] "Official" "mawla" "Official" "Official"
## [33] "Official" "Official" "Scribe" "Official"
Plotting our network
# R has an integrated plotting library that is pretty intuitive.
# This is different from Python where we had to import the matplotlib
# Library in tandem with other Python libraries
plot(net, edge.arrow.size = .4,
edge.curved =.1,
vertex.label.color = "black",
layout = layout_components) #There are other layout options that I will show next

# We can also produce multiple network visualizations as rows and columns
par(mfrow=c(2,2), mar=c(0,0,0,0)) # plots 4 figures as 2 x 2
plot(net, edge.arrow.size = .4, edge.curved =.1,
vertex.label.color = "black", layout = layout_with_fr)
plot(net, edge.arrow.size = .4, edge.curved =.1,
vertex.label.color = "black", layout = layout_on_sphere)
plot(net, edge.arrow.size = .4, edge.curved =.1,
vertex.label.color = "black", layout = layout_as_star)
plot(net, edge.arrow.size = .4, edge.curved =.1,
vertex.label.color = "black", layout = layout_on_grid)

# Let's add some more!
layouts <- grep("^layout_", ls("package:igraph"), value=TRUE)[-1]
layouts <- layouts[!grepl("bipartite|merge|norm|sugiyama|tree", layouts)]
par(mfrow=c(3,3), mar=c(1,1,1,1))
for (layout in layouts) {
print(layout)
l <-do.call(layout, list(net))
plot(net, vertex.label = NA, edge.arrow.mode=0, layout=l, main=layout)
#I removed the node label here to make it not as messy.
}
## [1] "layout_as_star"
## [1] "layout_components"
## [1] "layout_in_circle"
## [1] "layout_nicely"
## [1] "layout_on_grid"
## [1] "layout_on_sphere"
## [1] "layout_randomly"
## [1] "layout_with_dh"
## [1] "layout_with_drl"

## [1] "layout_with_fr"
## [1] "layout_with_gem"
## [1] "layout_with_graphopt"
## [1] "layout_with_kk"
## [1] "layout_with_lgl"
## [1] "layout_with_mds"

Visualizing Statistics!
deg <- degree(net, mode="all") #defining our "Kevin Bacon" factor
# We can make a histogram for our degrees
deg.dist <- degree_distribution(net, cumulative=T, mode="all")
plot(x=0:max(deg), y=1-deg.dist, pch=19, cex=1.2, col="blue",
xlab="Degree", ylab="Cumulative Frequency")

ceb <-cluster_edge_betweenness(net)
# Creating a Dendrogram
dendPlot(ceb, mode="hclust")

# Let's see the same dendrogram, but
# highlighted in network view
plot(ceb, net,edge.arrow.size = .4,
edge.curved =.1,
vertex.label.color = "black",
layout = layout_components)

Using visNetwork for Visualization
# With visNetwork, we can great an interactive
# visualization of our Papyri network
# that can allow the user to query different
# attributes related to the papyri to highlight
# the different relationships between social actors
# Here we import our network from our igraph library
# and create a new network in the visNetwork library
data <- toVisNetworkData(net)
nodes2 = data$nodes
edges2 = data$edges
# Basic command for visualization. Play with it!!
visNetwork(nodes2, edges2)
# Let's add some bells and whistles to this
# visualization, and try to get the most out of it.
nodes2$shape <- "dot"
nodes2$shadow <- TRUE
nodes2$borderWidth <- 2
edges2$color <- "gray"
edges2$arrows <- "to"
edges2$smooth <- TRUE
edges2$shadow <- FALSE
edges2$title <- paste("Citation", edges2$Citation) #This creates a popup with the citation
visNetwork(nodes2, edges2, width = "100%", height="700px") %>%
visEdges(shadow=c(FALSE),
arrows=c("to")
)%>%
visOptions(highlightNearest=TRUE,
selectedBy = "Rank",
nodesIdSelection = TRUE) %>%
visInteraction(navigationButtons = TRUE)
# Sadly, I haven't been able to figure out how to add
# multiple attributes to be searched and/or highlighted, etc.
# so, let's change things up a bit from the last visualization.
nodes2$shape <- "dot"
nodes2$shadow <- TRUE
nodes2$borderWidth <- 2
nodes2$color <-"tomato"
edges2$color <- "gray30"
edges2$arrows <- "to"
edges2$smooth <- TRUE
edges2$shadow <- FALSE
edges2$title <- paste("Letter Type:", edges2$Letter.Type) #This creates a popup with the Type of Letter
visNetwork(nodes2, edges2, width = "100%", height="700px") %>%
visEdges(shadow=c(FALSE),
arrows=c("to")
)%>%
visOptions(highlightNearest=TRUE,
selectedBy = "Location", # changed this to Location
nodesIdSelection = TRUE) %>%
visInteraction(navigationButtons = TRUE)
Spatial Networks with R
# This is an example of the geospatial capabilities with R
# For the following examples, I'd like to thank
# Katya Ognyanova's online documentation
# http://kateto.net/network-visualization
#
# I wanted to make a network map of this dossier over Egypt
# But I couldn't find the documentation in time to make such a map
# Instead, here's an example from the network documentation
# just to show that it is possible.
library('maps')
library('geosphere')
## Loading required package: sp
par(mfrow=c(2,2), mar=c(0,0,0,0))
map('usa', col='tomato', border='gray10', fill=TRUE, bg='gray30')
map('usa', col='orange', border='gray10', fill=TRUE, bg='gray30')
map('county', col='palegreen', border='gray10', fill=TRUE, bg='gray30')
map('world', col='skyblue', border='gray10', fill=TRUE, bg='gray30')
